#include "command.h"
#include <my_header.h>

// 初始化一个用来保存路径的栈
int pathStackInit(pathStack_t* pathStack){
    bzero(pathStack,sizeof(pathStack_t));
    pathStack->top=-1;
    pathStack->rootPathPointer=-1;// 只在curPathInit中初始化一次
    return 0;
}
// 出栈成功返回0，失败返回-1
int popStack(pathStack_t* pathStack){
    if(pathStack->top != -1){
        free(pathStack->pathArr[pathStack->top]);
        --pathStack->top;
    }else{
        return -1;
    }
    return 0;
}
// 压栈成功返回0，失败返回-1
int pushStack(pathStack_t* pathStack,const char * str){
    if((pathStack->top)<(PATHSTACK_MAXSIZE-1)){
        char* pathName = (char*)calloc(strlen(str)+1,sizeof(char));
        strcpy(pathName,str);
        printf("push: %s\n",pathName);
        ++(pathStack->top);
        pathStack->pathArr[pathStack->top]=pathName;
    }else{
        return -1;
    }
    return 0;
}
// 将字符串保存的路径 存在路径栈中,加入对../.的处理，加入对客户端眼里的绝对路径的处理，保证返回的是一个完整的绝对路径
// 正确处理返回0，发生错误返回-1
int saveStrPathToStack (char*path,pathStack_t* pathStack){
    char delim[] = "/";
    char* saveptr;
    char* token = strtok_r(path,delim,&saveptr);
    // 如果是客户端眼里的“绝对路径”,则从第一个和token相同的位置开始填入
    if(path[0]=='/'){
        printf("path[0]=/ \n");
        for(int i=pathStack->rootPathPointer+1;i<=pathStack->top;++i){
            printf("========i = %d========\n",i);
            if(strcmp(token,pathStack->pathArr[i])==0){
                int topCpy = pathStack->top;
                for(int j = i;j<=topCpy;++j){// 删掉从i到top的所有项
                    popStack(pathStack);// pop会改top,所以用topCpy
                    printf("===after pop top = %d\n",pathStack->top);
                }
                pathStack->top=i-1;
                break;
            }
        }
    }
    // 处理..和.的情况，并将token压栈
    while(token!=NULL){
        if(strcmp(token,"..")==0){
            if(pathStack->top==pathStack->rootPathPointer){
                printf("saveStrPathToStack: path error (to much ..)\n");
                return -1;// ../../../...太多，超出了允许访问的位置
            }
            popStack(pathStack);
        } else if(strcmp(token,".")!=0){
            pushStack(pathStack,token);
        }
        token = strtok_r(NULL,delim,&saveptr);
    }
    return 0;
}
//获取路径
int getPath(const pathStack_t* pathStack,char* result){       
    result[0]='\0';
    for(int i = 0;i<=pathStack->top;++i){
        strncat(result,"/",2);
        strncat(result,pathStack->pathArr[i],PATHNAME_MAXLEN);
    }   
    return 0;     
} 

// 打印路径栈
int printPathStack(pathStack_t* pathStack){
    printf("pathStack: ");
    if(pathStack->top==-1){
        printf("null\n");
    }
    for(int i = 0;i<=pathStack->top;++i){
        /* printf("%d:%s ",i,pathStack->pathArr[i]); */
        printf("%s ",pathStack->pathArr[i]);
    }
    printf("\n");
    return 0;
}
// 初始化表示客户端访问路径的路径栈，目前使用调用方传入的绝对路径
int curPathInit(pathStack_t* pCurPathStack, char* rootPath){
    bzero(pCurPathStack,sizeof(pathStack_t));
    pCurPathStack->top=-1;
    saveStrPathToStack(rootPath,pCurPathStack);
    pCurPathStack->rootPathPointer=pCurPathStack->top;
    return 0;
}

int my_cd(char *path, pathStack_t *pCurpathStack){
    char new_path[BUFSIZE] = {0};
    saveStrPathToStack(path, pCurpathStack); 
    getPath(pCurpathStack, new_path);
    if(!isDir(new_path)){
        return -1; 
    }
    return 0;
}

int my_ls(char *path, pathStack_t *pCurpathStack, char *result){
    pathStack_t *pathStack = pCurpathStack;
    char curPath[PATHNAME_MAXLEN] = {0};
    saveStrPathToStack(path, pathStack);
    getPath(pathStack, curPath);
    if(!isDir(curPath)){
        return -1;
    }
    DIR *dirp = opendir(curPath);
    ERROR_CHECK(dirp, NULL, "opendir failed");

    struct dirent *dirent_p;
    char buf[BUFSIZE] = {0};

    while((dirent_p = readdir(dirp)) != NULL){
        bzero(buf, sizeof(buf));
        sprintf(buf, "%s\t", dirent_p->d_name);
        strcat(result, buf);
    }
    closedir(dirp);
    return 0;
}

int my_rmFile(char *fileName, pathStack_t *pCurpathStack){
    pathStack_t *pathStack = pCurpathStack;
    saveStrPathToStack(fileName, pathStack);
    char new_path[BUFSIZE] = {0};
    getPath(pathStack, new_path);
    if(remove(new_path) != 0){
        return -1;
    }
    return 0;
}
// 将客户端当前访问的路径写在result中
int my_pwd(pathStack_t* pCurPathStack,char * result){
    if(pCurPathStack->top==pCurPathStack->rootPathPointer){
        result[0]='/';
    }
    for(int i = pCurPathStack->rootPathPointer+1;i<=pCurPathStack->top;++i){
        strncat(result,"/",2);
        strncat(result,pCurPathStack->pathArr[i],PATHNAME_MAXLEN);
    }
    return 0;
}

//用于判断从根目录到每一级目录是否能正常打开
int isDir(char *path){
    DIR *dir = opendir(path);
    if(dir){
        closedir(dir);
        return 1;
    }
    return 0;
}
int my_mkdir(char *dirName, pathStack_t *pCurpathStack){
    pathStack_t *pathStack = pCurpathStack;
    char new_path[BUFSIZE] = {0};
    saveStrPathToStack(dirName, pathStack);
    getPath(pathStack, new_path);

    if (mkdir(new_path, 0777) == -1) {
        // 创建失败处理
        return -1;
    }
    return 0;
}
int my_rmdir(char *dirName, pathStack_t *pCurpathStack){
    pathStack_t *pathStack = pCurpathStack;
    char new_path[BUFSIZE] = {0};
    saveStrPathToStack(dirName, pathStack);
    getPath(pathStack, new_path);

    if (rmdir(new_path) == -1) {
        // 删除失败处理
        return -1;
    } 
    return 0;
}


